Premier bloc de code : importation des librairies.

library(dplyr)
library(ggplot2)
library(tidytext)
library(tm)
library(knitr)
library(SemNetCleaner)
data("stop_words")
custom_stop_words <- tibble(word = c("plot","wild","slug","manipulation","apple","significant","free","led"),  
                                      lexicon = c("custom"))
combined_stop_words <- bind_rows(stop_words, custom_stop_words) # didn't find the way to combine tibbles earlier, wich is why some code chunks work with the two "stop words" dictionnaries separetly.

Deuxième bloc de code : définition des variables.

#----------------------------- 
earthworms <- read.csv("~/Documents/GitHub/EarthwormsMetanalysis/ExtractionBiblio/data_articles_metaanalyses.csv")
abstracts<-c()
#--------------------- 
names(earthworms)
## [1] "X"              "MA"             "Title"          "First.author"  
## [5] "Last.author"    "Abstract"       "OnResearchgate" "DOI"           
## [9] "rg_URL"
n = nrow(earthworms)

Troisième bloc de code: ajout d’une colonne “aboutEarthworms”.

earthworms <- earthworms %>% mutate(aboutEarthworms = rep(TRUE,n))

Quatrième bloc de code: Construction de la liste des abstracts.

abstracts=earthworms$Abstract

Cinquième bloc de code : Construction d’un dataframe de tokens.

 # Unnest tokens for the current abstract
unnested_tokens <- tibble(abstracts) %>%
unnest_tokens(word, abstracts)
# Append the unnested tokens to the list
unnested_tokens<-unnested_tokens%>%anti_join(stop_words)
unnested_tokens<-unnested_tokens %>% rowwise() %>% mutate(word = singularize(word))

Analyse du dataframe: trouver les mots les plus communs dans les quatre MA confondues.

ordre=unnested_tokens %>%
     count(word, sort = TRUE) %>%
     filter(n > 100) %>%
     mutate(word = reorder(word, n,decreasing=TRUE))

 ordre$word = factor(ordre$word,levels=rev(levels(ordre$word)))
 ggplot(ordre,aes(n, word)) +
     geom_col() +
     labs(y = NULL)


On peut voir que les trois mots les plus fréquents dans les articles des quatres métaanalyses confondues sont earthworm, soil et plant. On peut donc penser que les métaanalyses sont davantage portées sur le rôle écologique du ver de terre que sur l’étude des vers de terre à part entière.


MA1: “Soil chemistry turned upside down: a meta-analysis of invasive earthworm effects on soil chemical properties”
MA2: “Earthworms affect plant growth and resistance against herbivores: A meta-analysis”
MA3: “The unseen invaders: introduced earthworms as drivers of change in plant communities in North American forests (a meta-analysis)”
MA4: “Earthworms increase plant production: a meta-analysis”

Création de subsets correspondant aux 4 MA individuellement, afin de pouvoir les comparer entre elles.

Import subset MA1:

splitedData <- split(earthworms,earthworms$MA)

abstracts1<-c()
MA1 <- splitedData$MA1
nMA1 <- nrow(MA1)
abstracts1<-MA1$Abstract
unnested_tokens1 <- tibble(abstracts1) %>%
unnest_tokens(word, abstracts1)
unnested_tokens1<-unnested_tokens1 %>% anti_join(stop_words)
unnested_tokens1<-unnested_tokens1 %>% rowwise() %>% mutate(word = singularize(word))

Import subset MA2:

abstracts2<-c()
MA2 <- splitedData$MA2
nMA2 <- nrow(MA2)
abstracts2<-MA2$Abstract
unnested_tokens2 <- tibble(abstracts2) %>%
unnest_tokens(word, abstracts2)
unnested_tokens2<-unnested_tokens2 %>% anti_join(stop_words)
unnested_tokens2<-unnested_tokens2 %>% rowwise() %>% mutate(word = singularize(word))

Import subset MA3:

abstracts3<-c()
MA3 <- splitedData$MA3
nMA3 <- nrow(MA3)
abstracts3<-MA3$Abstract
unnested_tokens3 <- tibble(abstracts3) %>%
unnest_tokens(word, abstracts3)
unnested_tokens3<-unnested_tokens3 %>% anti_join(stop_words)
unnested_tokens3<-unnested_tokens3 %>% rowwise() %>% mutate(word = singularize(word))

Import subset MA4:

abstracts4<-c()
MA4 <- splitedData$MA4
nMA4 <- nrow(MA4)
abstracts4<-MA4$Abstract
unnested_tokens4 <- tibble(abstracts4) %>%
unnest_tokens(word, abstracts4)
unnested_tokens4<-unnested_tokens4 %>% anti_join(stop_words)
unnested_tokens4<-unnested_tokens4 %>% rowwise() %>% mutate(word = singularize(word))

Création des quatre plots:

Plot MA1 :

ordre1=unnested_tokens1 %>%
     count(word, sort = TRUE) %>%
     filter(n > 25) %>%
     mutate(word = reorder(word, n,decreasing=TRUE))

 ordre1$word = factor(ordre1$word,levels=rev(levels(ordre1$word)))
 plot1<-ggplot(ordre1,aes(n, word)) +
     geom_col() +
     labs(y = NULL)

Plot MA2 :

ordre2=unnested_tokens2 %>%
     count(word, sort = TRUE) %>%
     filter(n > 25) %>%
     mutate(word = reorder(word, n,decreasing=TRUE))

 ordre2$word = factor(ordre2$word,levels=rev(levels(ordre2$word)))
 plot2<-ggplot(ordre2,aes(n, word)) +
     geom_col() +
     labs(y = NULL)

Plot MA3 :

ordre3=unnested_tokens3 %>%
     count(word, sort = TRUE) %>%
     filter(n > 25) %>%
     mutate(word = reorder(word, n,decreasing=TRUE))

 ordre3$word = factor(ordre3$word,levels=rev(levels(ordre3$word)))
 plot3<-ggplot(ordre3,aes(n, word)) +
     geom_col() +
     labs(y = NULL)

Plot MA4:

ordre4=unnested_tokens4 %>%
     count(word, sort = TRUE) %>%
     filter(n > 25) %>%
     mutate(word = reorder(word, n,decreasing=TRUE))

 ordre4$word = factor(ordre4$word,levels=rev(levels(ordre4$word)))
 plot4<-ggplot(ordre4,aes(n, word)) +
     geom_col() +
     labs(y = NULL)

Comparaison des quatre MA:

Quels sont les mots les plus communs dans chacunes des MA?

library(egg)
ggarrange(plot1,plot2,plot3,plot4,widths = c(5,5),labels = c("1","2","3","4"))


On remarque que les mots les plus fréquents dans les articles des métaanalyses sont: - earthworm, soil et forest pour la MA1 (qui semble donc s’intéresser plus particulièrement à l’écosystème forestier). - plant, earthworm et effect pour la MA2 (qui semble donc vouloir étudier précisément les effets des vers de terre sur les plantes). - earthworm, specie, et plant pour la MA3 (qui semble donc s’intéresser plus particulièrement à certaines espèces de vers de terre et leurs relations avec les plantes). - earthworm, plant et soil pour la MA4 (qui semble donc étudier l’influence des vers de terre sur les sols et les plantes).
MA1: “Soil chemistry turned upside down: a meta-analysis of invasive earthworm effects on soil chemical properties”
MA2: “Earthworms affect plant growth and resistance against herbivores: A meta-analysis”
MA3: “The unseen invaders: introduced earthworms as drivers of change in plant communities in North American forests (a meta-analysis)”
MA4: “Earthworms increase plant production: a meta-analysis”

# DataFrame pour comparer les fréquences des 4 MA:

library(tidyr)

frequency1 <- bind_rows(mutate(unnested_tokens1, author = "MA1"),
                       mutate(unnested_tokens2, author = "MA2"), 
                       mutate(unnested_tokens3, author = "MA3"),
                       mutate(unnested_tokens4, author = "MA4"))%>% 
  mutate(word = stringr::str_extract(word, "[a-z']+")) %>%
  count(author, word) %>%
  group_by(author) %>%
  mutate(proportion = n / sum(n)) %>% 
  select(-n) %>% 
  pivot_wider(names_from = author, values_from = proportion) %>%
  pivot_longer(cols=c('MA2','MA3','MA4'),
               names_to = "author", values_to = "proportion")
frequency2 <- bind_rows(mutate(unnested_tokens1, author = "MA1"),
                       mutate(unnested_tokens2, author = "MA2"), 
                       mutate(unnested_tokens3, author = "MA3"),
                       mutate(unnested_tokens4, author = "MA4"))%>% 
  mutate(word = stringr::str_extract(word, "[a-z']+")) %>%
  count(author, word) %>%
  group_by(author) %>%
  mutate(proportion = n / sum(n)) %>% 
  select(-n) %>% 
  pivot_wider(names_from = author, values_from = proportion) %>%
  pivot_longer(cols=c('MA1','MA3','MA4'),
               names_to = "author", values_to = "proportion")
frequency3 <- bind_rows(mutate(unnested_tokens1, author = "MA1"),
                       mutate(unnested_tokens2, author = "MA2"), 
                       mutate(unnested_tokens3, author = "MA3"),
                       mutate(unnested_tokens4, author = "MA4"))%>% 
  mutate(word = stringr::str_extract(word, "[a-z']+")) %>%
  count(author, word) %>%
  group_by(author) %>%
  mutate(proportion = n / sum(n)) %>% 
  select(-n) %>% 
  pivot_wider(names_from = author, values_from = proportion) %>%
  pivot_longer(cols=c('MA1','MA2','MA4'),
               names_to = "author", values_to = "proportion")

Graphe de comparaison des fréquences:

library(scales)

# expect a warning about rows with missing values being removed
ggplot(frequency1, aes(x = proportion, y = `MA1`, 
                      color = abs(`MA1` - proportion))) +
  geom_abline(color = "gray40", lty = 2) +
  geom_jitter(alpha = 0.1, size = 2.5, width = 0.3, height = 0.3) +
  geom_text(aes(label = word), check_overlap = TRUE, vjust = 1.5) +
  scale_x_log10(labels = percent_format()) +
  scale_y_log10(labels = percent_format()) +
  scale_color_gradient(limits = c(0, 0.001), 
                       low = "darkslategray4", high = "gray75") +
  facet_wrap(~author, ncol = 2) +
  theme(legend.position="none") +
  labs(y = "MA1", x = NULL)

MA1 vs MA2 :

  • Les mots proches de la ligne dans ces graphiques ont des fréquences similaires dans les deux ensembles de textes, soit, dans l’ordre croissant: “accelerated”, “affecting”,“based”, “dweling”, “day”, “change”, “common”, “availability”, “negative”, “abundance”, “content”, “increase”, “activity”, “concentration”, “litter”, “biomass”, “specie”, “soil”, “earthworm”. On remarque que les mots les plus fréquents semblent être plus directement liés au sujet de l’article que les autres, qui paraissent plus générique au vocabulaire scientifique en écologie.

  • Les mots “invasion”, “carbon”, “layer” et “loss” sont plus fréquents dans la MA1 que dans la MA2, tandis que les mots “plant”, “root”, “shoot” et “grass” sont plus fréquents dans la MA2 que de la MA1.

  • Les mots “specie”, “effect”, “soil” et “earthworm” représentent entre 1 et 10% des mots totaux de chaque métaanalyse pour les métaanalyses 1 et 2 (échelle logarithmique).

MA1 vs MA3 :

  • Les mots proches de la ligne dans ces graphiques ont des fréquences similaires dans les deux ensembles de textes, soit, dans l’ordre croissant: “assessed”, “basal”, “abundant”, “abiotic”, “day”, “biotic”, “avalability”, “compared”, “america”, “invasive”, “european”, “abundance”, “study”, “nutrient”, “increased”, “exotic”, “ecosystem”, “impact”, “litter”, “biomass”, “effect”, “invasion”, “forest”, “specie”, “soil”, “earthworm”. On remarque que certains mots dont la fréquence est proches pourraient peut-être faire partie du même groupe de mots (comme “invasive european”,“nutrient increased”, “ecosystem impact” ou encore “litter biomass”.)

  • Les mots “pool”, “carbon”, et “microbial sont plus fréquents dans la MA1 que dans la MA3, tandis que les mots “cover”, “tree”, “density” et “plant” sont plus fréquents dans la MA3 que de la MA1.

  • Les mots “specie”, “forest,”soil” et “earthworm” représentent entre 1 et 10% des mots totaux de chaque métaanalyse pour les métaanalyses 1 et 3 (échelle logarithmique). On peut remarquer une forte ressemblance avec les résultats obtenus entre les MA 1 et 2.

MA1 vs MA4 :

  • Les mots proches de la ligne dans ces graphiques ont des fréquences similaires dans les deux ensembles de textes, soit, dans l’ordre croissant: “access”,“acquisition”,“data”,“australia”, “amonium”, “applied”, “analysis”, “due”, “mass”, “direct”, “affect”, “system”, “native”, “ecosystem”, “density”, “experiment”, “organic”, “activity”, “litter”, “community”, “biomass”, “specie”, effect, earthworm. On remarque que certains mots dont la fréquence est proches pourraient peut-être faire partie du même groupe de mots (comme acquisition data, direct effect, native ecosystem, ou encore litter community).

  • Les mots “forest”,“invasion”, “carbon” et “floor” sont plus fréquents dans la MA1 que dans la MA4, tandis que les mots “invader”, “functional”, “grassland”, “grass” et “plant” sont plus fréquents dans la MA4 que de la MA1.

  • Les mots “effect” et “earthworm” représentent entre 1 et 10% des mots totaux de chaque métaanalyse pour les métaanalyses 1 et 4 (échelle logarithmique).

Analyse globale:

  • Dans cette configuration, la MA1 et la MA4 semblent être les plus similaires en termes de fréquences de mots (nuage de points davantage resserré autour de la droite.)

  • Dans cette configuration, la MA1 et la MA2 semblent être les moins similaires en termes de fréquences de mots (nuage de points davantage dispersé autour de la droite.)

Tests de corrélation:

Quel est le degré de corrélation entre les fréquences de mots de chaque métaanalyse ?

MA2 VS MA1

cor.test(data = frequency1[frequency1$author == "MA2",],
         ~ proportion + `MA1`)
## 
##  Pearson's product-moment correlation
## 
## data:  proportion and MA1
## t = 17.22, df = 362, p-value < 2.2e-16
## alternative hypothesis: true correlation is not equal to 0
## 95 percent confidence interval:
##  0.6103556 0.7239044
## sample estimates:
##       cor 
## 0.6710462

MA3 VS MA1

cor.test(data = frequency1[frequency1$author == "MA3",],
         ~ proportion + `MA1`)
## 
##  Pearson's product-moment correlation
## 
## data:  proportion and MA1
## t = 26.491, df = 395, p-value < 2.2e-16
## alternative hypothesis: true correlation is not equal to 0
## 95 percent confidence interval:
##  0.7614356 0.8327697
## sample estimates:
##       cor 
## 0.7999107

MA4 VS MA1

cor.test(data = frequency1[frequency1$author == "MA4",],
         ~ proportion + `MA1`)
## 
##  Pearson's product-moment correlation
## 
## data:  proportion and MA1
## t = 30.246, df = 591, p-value < 2.2e-16
## alternative hypothesis: true correlation is not equal to 0
## 95 percent confidence interval:
##  0.7457166 0.8091686
## sample estimates:
##       cor 
## 0.7794336

MA3 VS MA2

cor.test(data = frequency2[frequency2$author == "MA3",],
         ~ proportion + `MA2`)
## 
##  Pearson's product-moment correlation
## 
## data:  proportion and MA2
## t = 19.668, df = 228, p-value < 2.2e-16
## alternative hypothesis: true correlation is not equal to 0
## 95 percent confidence interval:
##  0.7397460 0.8367073
## sample estimates:
##       cor 
## 0.7932011

MA4 VS MA2

cor.test(data = frequency2[frequency2$author == "MA4",],
         ~ proportion + `MA2`)
## 
##  Pearson's product-moment correlation
## 
## data:  proportion and MA2
## t = 33.547, df = 529, p-value < 2.2e-16
## alternative hypothesis: true correlation is not equal to 0
## 95 percent confidence interval:
##  0.7955062 0.8501921
## sample estimates:
##      cor 
## 0.824768

MA4 VS MA3

cor.test(data = frequency3[frequency3$author == "MA4",],
         ~ proportion + `MA3`)
## 
##  Pearson's product-moment correlation
## 
## data:  proportion and MA3
## t = 19.575, df = 316, p-value < 2.2e-16
## alternative hypothesis: true correlation is not equal to 0
## 95 percent confidence interval:
##  0.6861759 0.7862586
## sample estimates:
##       cor 
## 0.7402917

Tableau récapitulatif :

MA1 MA2 MA3 MA4
MA1 - 0.671 0.799 0.779
MA2 - 0.793 0.825
MA3 - 0.740
MA4 -


MA1: “Soil chemistry turned upside down: a meta-analysis of invasive earthworm effects on soil chemical properties”
MA2: “Earthworms affect plant growth and resistance against herbivores: A meta-analysis”
MA3: “The unseen invaders: introduced earthworms as drivers of change in plant communities in North American forests (a meta-analysis)”
MA4: “Earthworms increase plant production: a meta-analysis”

D’après le tableau ci-dessus, on peut voir que le choix de mots est le plus corrélé (correlation de Pearson) entre la MA2 et la MA4 (r²=0.825), tandis que le choix de mots est le moins corrélé (corrélation de Pearson) entre la MA1 et la MA2 (r²=0.671).

Analyse de sentiment:

Premiers graphiques.

On commence par construire des Tibbles contenant chaque mot exprimant un sentiment positif ou négatif (colonne word), puis on compte le nombre d’occurence de chaque mot (colonne n).

library(tidytext)
bing<-get_sentiments("bing")

senti1<-unnested_tokens1 %>%
  inner_join(bing) %>%
  count(word, sort = TRUE)

senti2<-unnested_tokens2 %>%
  inner_join(bing) %>%
  count(word, sort = TRUE)

senti3<-unnested_tokens3 %>%
  inner_join(bing) %>%
  count(word, sort = TRUE)

senti4<-unnested_tokens4 %>%
  inner_join(bing) %>%
  count(word, sort = TRUE)

On ne conserve que les dix premières valeurs et les dix dernières valeurs, afin de pouvoir produire des graphiques plus lisibles ne conservant que les valeurs extrêmes.

library(tidyr)
MA1_senti <- senti1 %>%
  inner_join(get_sentiments("bing")) %>%
  anti_join(custom_stop_words, by = c("word")) %>%
  pivot_wider(names_from = sentiment, values_from = n, values_fill = 0) %>% 
  mutate(sentiment = positive - negative)
sub1_MA1_senti<-MA1_senti %>%
    arrange(sentiment) %>%
    slice(1:10)
sub2_MA1_senti<-MA1_senti %>%
    arrange(desc(sentiment)) %>%
    slice(1:10)
sub_MA1_senti<-bind_rows(sub1_MA1_senti, sub2_MA1_senti)

On réalise un premier barplot de sentiment à titre d’exemple, en associant à chaque mot positif l’indice +1, et à chaque mot négatif l’indice -1. On représente ensuite cela graphiquement chaque mot en abscisse et la somme de ses indices (dont la valeur dépend de sa connotation et du nombre d’occurences) en ordonnées. On peut noter que certains mots neutres dans un contexte scientifique (comme “plot” ou “manipulation”) ont été rajoutés au dictionaire de “stop words”, pour éviter qu’ils soient considérés à tort comme des mots à valence négative.

ggplot(sub_MA1_senti, aes(x = word, y = sentiment, fill = factor(sign(sentiment)))) +
  geom_bar(stat = "identity") +
  labs(x = "Word", y = "Sentiment Score", fill = "Sentiment") +
  theme_minimal() +
  theme(axis.text.x = element_text(angle = 45, hjust = 1))

On répète le processus pour comparer les métaanalyses 1,2,3 et 4.

library(tidyr)
library(ggplot2)

plot_sentiment_subset <- function(senti) {
  MA_senti <- senti %>%
    inner_join(get_sentiments("bing")) %>%
    pivot_wider(names_from = sentiment, values_from = n, values_fill = 0) %>% 
    mutate(sentiment = positive - negative)
  
  sub1_MA_senti <- MA_senti %>%
    anti_join(custom_stop_words, by = c("word")) %>%
    arrange(sentiment) %>%
    slice(1:5)
  
  sub2_MA_senti <- MA_senti %>%
    anti_join(custom_stop_words, by = c("word")) %>%
    arrange(desc(sentiment)) %>%
    slice(1:5)
  
  sub_MA_senti <- bind_rows(sub1_MA_senti, sub2_MA_senti)
  
  ggplot(sub_MA_senti, aes(x = word, y = sentiment, fill = factor(sign(sentiment)))) +
    geom_bar(stat = "identity") +
    labs(x = "Word", y = "Sentiment Score", fill = "Sentiment") +
    theme_minimal() +
    theme(axis.text.x = element_text(angle = 45, hjust = 1))
}

plot_senti1<-plot_sentiment_subset(senti1)
plot_senti2<-plot_sentiment_subset(senti2)
plot_senti3<-plot_sentiment_subset(senti3)
plot_senti4<-plot_sentiment_subset(senti4)
library(egg)
ggarrange(plot_senti1,plot_senti2,plot_senti3,plot_senti4,widths = c(2,2),labels = c("1","2","3","4"))

Tout d’abord, il est immportant de noter que tous les graphes n’ont pas les mêmes échelles ; les MA1 et 4 semblent avoir des échelles de sentiment comparables ([-20;10] et [-10;20]) et cela vaut aussi pour les MA2 et 3 ([-10;5] et [-5;10])

On peut constater que le mot positif “abundance” est retrouvé dans la plupart de métaanalyses (1,2 et 3). Il serait cependant nécessaire d’inspecter des unités textuelles plus larges pour interpréter au mieux ce résultat, car la signification de ces mots peut grandement dépendre des autres mots auquels ils sont associés et du contexte. le mot “dynamic n’est retrouvé que dans les MA1 et 3. A l’inverse, Le mot “unaffected” n’est quant à lui retrouvé que dans les MA2 et 4. On peut émettre l’hypothèse que les MA2 et 4 se focalisent sur les mécanismes de préservation et de résistance, alors que la 1 et la 3 sont davantage axées sur la dynamique des écosystèmes.

On peut constater qu’il n’y a aucun mot négatif commun à tous les corpus. Cependant, les mots “invasive” ou “invader” sont retrouvées dans las MA 1, 3 et 4, ce qui sous-entend que la MA2 s’intéresse moins aux espèces invasives que les trois autres. On peut aussi remarquer que le mot “loss” n’est retrouvé que dans les MA1 et 4, ce qui semble indiquer que les effets négatifs relevés ne sont pas forcément liés à des pertes de caractéristiques. Le mot “severity”, à l’inverse, n’est retrouvé que dans les MA3 et 4, ce qui signifie peut-être qu’elles sont plus “quantitatives” que les deux autres. On peut enfin constater que le mot “loss” est le mot avec le score négatif le plus important des quatre graphiques, représenté dans la MA1.


MA1: “Soil chemistry turned upside down: a meta-analysis of invasive earthworm effects on soil chemical properties”
MA2: “Earthworms affect plant growth and resistance against herbivores: A meta-analysis”
MA3: “The unseen invaders: introduced earthworms as drivers of change in plant communities in North American forests (a meta-analysis)”
MA4: “Earthworms increase plant production: a meta-analysis”

Contribution de chaque terme au score final de sentiment.

bing_word_counts1 <- unnested_tokens1 %>%
  inner_join(get_sentiments("bing")) %>%
  count(word, sentiment, sort = TRUE) %>%
  mutate(MA="MA1") %>%
  ungroup() 
bing_word_counts2 <- unnested_tokens2 %>%
  inner_join(get_sentiments("bing")) %>%
  count(word, sentiment, sort = TRUE) %>%
  mutate(MA="MA2") %>%
  ungroup()
bing_word_counts3 <- unnested_tokens3 %>%
  inner_join(get_sentiments("bing")) %>%
  count(word, sentiment, sort = TRUE) %>%
  mutate(MA="MA3") %>%
  ungroup() 
bing_word_counts4 <- unnested_tokens4 %>%
  inner_join(get_sentiments("bing")) %>%
  count(word, sentiment, sort = TRUE) %>%
  mutate(MA="MA4") %>%
  ungroup()
contrib1<-bing_word_counts1 %>%
  anti_join(custom_stop_words, by = c("word")) %>%
  group_by(sentiment) %>%
  slice_max(n, n = 10) %>% 
  ungroup() %>%
  mutate(word = reorder(word, n)) %>%
  ggplot(aes(n, word, fill = sentiment)) +
  geom_col(show.legend = FALSE) +
  facet_wrap(~sentiment, scales = "free_y") +
  labs(x = "Contribution to sentiment",
       y = NULL)

contrib2<-bing_word_counts2 %>%
  anti_join(custom_stop_words, by = c("word")) %>%
  group_by(sentiment) %>%
  slice_max(n, n = 10) %>% 
  ungroup() %>%
  mutate(word = reorder(word, n)) %>%
  ggplot(aes(n, word, fill = sentiment)) +
  geom_col(show.legend = FALSE) +
  facet_wrap(~sentiment, scales = "free_y") +
  labs(x = "Contribution to sentiment",
       y = NULL)

contrib3<-bing_word_counts3 %>%
  anti_join(custom_stop_words, by = c("word")) %>%
  group_by(sentiment) %>%
  slice_max(n, n = 10) %>% 
  ungroup() %>%
  mutate(word = reorder(word, n)) %>%
  ggplot(aes(n, word, fill = sentiment)) +
  geom_col(show.legend = FALSE) +
  facet_wrap(~sentiment, scales = "free_y") +
  labs(x = "Contribution to sentiment",
       y = NULL)

contrib4<-bing_word_counts4 %>%
  anti_join(custom_stop_words, by = c("word")) %>%
  group_by(sentiment) %>%
  slice_max(n, n = 10) %>% 
  ungroup() %>%
  mutate(word = reorder(word, n)) %>%
  ggplot(aes(n, word, fill = sentiment)) +
  geom_col(show.legend = FALSE) +
  facet_wrap(~sentiment, scales = "free_y") +
  labs(x = "Contribution to sentiment",
       y = NULL)
library(egg)
ggarrange(contrib1,contrib2,contrib3,contrib4,widths = c(2,2),labels = c("1","2","3","4"))

Tout d’abord, il faut noter que les graphiques ne sont pas à la même échelle en abscisse. Cela ne pose en théorie pas de problème pour interpréter les résultats au cas par cas, mais cela rentrera en jeux lors d’éventuelles comparaisons entre métaanalyses.

Les quatre mots positifs les plus importants en contribution sont:
* MA1: “abundance”, dynamic”, “dominated”,“positive”.
* MA2: “enhanced”, “abundance”, “variety”,“unaffected”.
* MA3: “richness”, “abundance”, “leading”, “dynamic”.
* MA4: “unnaffected”, “enhanced”,“enhance”,“positive”.

Le mot “unaffected” compte parmi les 4 premiers dans les MA2 et 4 (qui semblent davantage s’intéresser aux plantes), là où le mot “positive” compte parmi les quatre premiers pour les MA1 et 4, qui semblent se focaliser sur les sols (d’après les titres). Cela pourrait vouloir dire que, d’après ces métaanalyse, les vers de terre ont un impact plutôt positif sur les sols et les plantes. Cependant, l’approche en unités textuelles plus larges, comme les n-grames, semble souhaitable pour éviter les contresens. Par ailleurs, le mot “abundance” est dans les premiers pour les MA 1, 2 et 3, mais pas pour la MA4, ce qui pourrait signifier qu’elle est moins orientée sur la richesse écosystémique que les autres. De plus, la présence des mots “enhanced” et “enhance” semble montrer que, comme son nom l’indique, elle choisit une approche plus quantitative (étude de la production) que les autres.

Les quatre mots négatifs les plus importants en contribution (en ne comptant pas “rocky”, qui dans ce contexte est sans doute employé au sens propre de “rocheux/rocailleux”, comme par exemple dans le groupe de mots “Rocky area”.) sont:
* MA1: “loss”, “invasive”, “negative”, “poorly”.
* MA2: “drought”, “negative”, “dead”,“absence”.
* MA3: “invasive”, “burned”, “severity”,“negative”.
* MA4: “invader”, “severity”, “infested”,“absence”.
On remarque d’abord qu’aucun des mots négatifs relevés n’est présent dans les quatre premiers de toutes les métaanalyses. Cela dit, le mot “negative” semble être le mieux réparti, car présent dans 3 MA sur les 4 (1,2 et 3). De la même façon, on peut aussi noter que les mots “invasive” et “invader” sont aussi présents dans les 4 premiers de 3 MA sur les 4 (1,3 et 4, respectivement en 2e et 1er position pour “invasive” et 1er position pour “invader”).
On peut aussi noter que “invasive” semble souvent dans le même groupe que “negative (MA1,3), tandis que le mot “invader”, lui, semble plutôt associé avec “infested” (MA4).
La MA2 semble sortir du lot, avec des mots uniques comme “drought” et “dead”. Cela pourrait indiquer que l’étude s’intéresse davantage aux effets des vers de terre sur la physiologie végétale en tant que telle plutôt qu’à leurs aoports écologiques ou de production, ce qui semble en accord avec le titre donné à cette métaanalyse.

Da façon simpliste, il semble donc possible, à partir de ces graphiques, de proposer une première catégorisation comme suit:
- MA1/MA3: étude de l’impact écologique des vers de terre sur les écosystèmes.
- MA2: étude des effets des vers de terre sur la physiologie végétale.
- MA4: étude de l’influence des vers de terre invasifs sur la production végétale.

Cependant, il serait peut-être nécessaire d’étudier des unités textuelles plus larges, comme par exemple les phrases ou les n-grames, pour éviter au maximum le risque de contresens.


MA1: “Soil chemistry turned upside down: a meta-analysis of invasive earthworm effects on soil chemical properties”
MA2: “Earthworms affect plant growth and resistance against herbivores: A meta-analysis”
MA3: “The unseen invaders: introduced earthworms as drivers of change in plant communities in North American forests (a meta-analysis)”
MA4: “Earthworms increase plant production: a meta-analysis”

Représentation visuelle de la fréquence des mots: Wordclouds

Wordcloud MA1: “Soil chemistry turned upside down: a meta-analysis of invasive earthworm effects on soil chemical properties”

Visuellement, on peut voir sur le nuage de mots que les termes prépondérants dans la MA1 sont : “earthworm”,“soil”,“forest” et “effect”. On peut remarquer aussi que le mot “invasion” semble aussi relativement fréquent, ce qui est cohérent avec le titre de l’article (“invasive earthworms”). La prépondérance du mot “earthworm” sur les autres semble confirmer que les vers de terre sont le sujet principal de cette métaanalyse.

library(wordcloud)
library(dplyr)

unnested_tokens1 %>%
  anti_join(stop_words) %>%
  count(word) %>%
  with(wordcloud(word, n, max.words = 50))

cloud1 <- recordPlot()

Wordcloud MA2: “Earthworms affect plant growth and resistance against herbivores: A meta-analysis”

Visuellement, on peut voir sur le nuage de mots que les termes prépondérants dans la MA2 sont : “plant”,“earthworm”,“aphid”, “soil” et “effect”. D’autres mots tel que “increased”, “community”, “interaction”, “presence” ou “biomass” semblent décrire un processus biologique dynamique. La prépondérance de “plant” sur les autres semble confirmer que la biologie végétale en lien avec les vers de terre est le thème principal de cette métaanalyse.

unnested_tokens2 %>%
  anti_join(stop_words) %>%
  count(word) %>%
  with(wordcloud(word, n, max.words = 50))

cloud2 <- recordPlot()

Wordcloud MA3: “The unseen invaders: introduced earthworms as drivers of change in plant communities in North American forests (a meta-analysis)”

Visuellement, on peut voir sur le nuage de mots que les termes prépondérants dans la MA3 sont : “earthworm”,“specie”, “plant” et “forest”. La prépondérance des mots “earthworm” et “specie” sur les autres semble confirmer que la métaanlyse s’intéresse en particulier à la façon dont les différentes espèces de vers de terre (natives ou introduite) influent sur l’écosystème global (et notamment l’écosystème forestier). D’autres mots tel que “invasion”, “community”, “interaction”, “presence” ou “biomass” semblent décrire un processus écologique dynamique.

unnested_tokens3 %>%
  anti_join(stop_words) %>%
  count(word) %>%
  with(wordcloud(word, n, max.words = 50))

cloud3 <- recordPlot()

Wordcloud MA4: “Earthworms increase plant production: a meta-analysis”

Visuellement, on peut voir sur le nuage de mots que les termes prépondérants dans la MA4 sont : “earthworm”,“soil”, “plant” et “increased”. La prépondérance de ces mots semble confirmer que cette métaanalyse montre un effet positif (“increased” et “production”) des vers de terre sur les plantes, via, probablement, une amélioration de la qualité des sols (voir des mots comme “decomposer”, “nurient”, “growth”, “organic”, qui sont souvent utilisés pour décrire les sols favorables à la croissance végétale).

unnested_tokens4 %>%
  anti_join(stop_words) %>%
  count(word) %>%
  with(wordcloud(word, n, max.words = 50))

cloud4 <- recordPlot()

Wordcloud: coloration en fonction de la valence des mots (bleu: Positif / rouge: Négatif)

Wordcloud MA1: “Soil chemistry turned upside down: a meta-analysis of invasive earthworm effects on soil chemical properties”

Visuellement, on peut voir sur le nuage de mots que les termes positfs prépondérants dans la MA1 sont “abundance”, “dynamic” et dominated, tandis que les termes négatifs prépondérants sont “loss”,“invasive” et “negative”. On remarque tout d’abord que ces résultats sont très différents de ceux trouvés dans la partie précédente pour la même métaanalyse (Wordclouds: Wordcloud MA1) à cause de l’ajout de la variable “sentiment”. On peut aussi constater grâce à la taille de chaque mot du nuage et à la quantité de mots négatifs et positifs que la métaanalyse 1 semble porter un avis plutôt négatif sur son sujet d’étude (ici, l’impact des vers de terre sur les écosystèmes).

library(reshape2)

unnested_tokens1 %>%
  anti_join(custom_stop_words, by = c("word")) %>%
  inner_join(get_sentiments("bing")) %>%
  count(word, sentiment, sort = TRUE) %>%
  acast(word ~ sentiment, value.var = "n", fill = 0) %>%
  comparison.cloud(colors = c("red", "blue"),
                   max.words = 100)

cloud_senti1<-recordPlot()

Wordcloud MA2: “Earthworms affect plant growth and resistance against herbivores: A meta-analysis”

Visuellement, on peut voir sur le nuage de mots que les termes positfs prépondérants dans la MA2 sont “enhanced”, “abundance” et variety, tandis que les termes négatifs prépondérants sont “drought”,“negative” et “dead”. On remarque tout d’abord que ces résultats sont très différents de ceux trouvés dans la partie précédente pour la même métaanalyse (Wordclouds: Wordcloud MA2) à cause de l’ajout de la variable “sentiment”. On peut aussi constater grâce à la taille de chaque mot du nuage et à la quantité de mots négatifs et positifs que la métaanalyse 2 semble porter un jugement moins tranché que la précédente sur son sujet d’étude, sans dominance claire des mots positifs ou des mots négatifs (même si le mot le plus représenté, “drought”, est un mot à valence négative).

unnested_tokens2 %>%
  anti_join(custom_stop_words, by = c("word")) %>%
  inner_join(get_sentiments("bing")) %>%
  count(word, sentiment, sort = TRUE) %>%
  acast(word ~ sentiment, value.var = "n", fill = 0) %>%
  comparison.cloud(colors = c("red", "blue"),
                   max.words = 100)

cloud_senti2<-recordPlot()

Wordcloud MA3: “The unseen invaders: introduced earthworms as drivers of change in plant communities in North American forests (a meta-analysis)”

Visuellement, on peut voir sur le nuage de mots que les termes positfs prépondérants dans la MA3 sont “richness”, “abundance” et significant, tandis que les termes négatifs prépondérants sont “invasive”,“burned” et “negative”. On remarque tout d’abord que ces résultats sont très différents de ceux trouvés dans la partie précédente pour la même métaanalyse (Wordclouds: Wordcloud MA3) à cause de l’ajout de la variable “sentiment”. On peut aussi constater grâce à la taille de chaque mot du nuage et à la quantité de mots négatifs et positifs que la métaanalyse 3 semble aussi porter jugement nuancé sur son sujet d’étude, sans dominance claire des mots positifs ou des mots négatifs (même si le mot le plus représenté, “richness”, est un mot à valence positive). On peut cependant constater par la présence du mot “invasive” et du mot “invader” dans le même nuage que cette métaanalyse semble davantage parler d’invasion biologique que les autres.

unnested_tokens3 %>%
  anti_join(custom_stop_words, by = c("word")) %>%
  inner_join(get_sentiments("bing")) %>%
  count(word, sentiment, sort = TRUE) %>%
  acast(word ~ sentiment, value.var = "n", fill = 0) %>%
  comparison.cloud(colors = c("red", "blue"),
                   max.words = 100)

cloud_senti3<-recordPlot()

Wordcloud MA4: “Earthworms increase plant production: a meta-analysis”

Visuellement, on peut voir sur le nuage de mots que les termes positfs prépondérants dans la MA4 sont “significant”, “unaffected” et “enhance”, tandis que les termes négatifs prépondérants sont “invader”,“severity” et “infested”. On remarque tout d’abord que ces résultats sont très différents de ceux trouvés dans la partie précédente pour la même métaanalyse (Wordclouds: Wordcloud MA4) à cause de l’ajout de la variable “sentiment”. On peut cependant constater par la présence des mots “infested”, “severity”, “absence” et “invader” que la métaanalyse semble porter un jugement plutôt négatif, ce qui semble étonnant au vu du titre de la métaanalyse. Par ailleurs, même si le mot central, “significant”, est théoriquement le plus fréquent, on pourrait penser que la métaanalyse contient plus de mots positifs que de mots négatifs. Cependant, nous avons déjà vu que dans un contexte scientifique, la valence de ce mot dépend beaucoup du groue de mots auquel il est associé.

unnested_tokens4 %>%
  anti_join(custom_stop_words, by = c("word")) %>%
  inner_join(get_sentiments("bing")) %>%
  count(word, sentiment, sort = TRUE) %>%
  acast(word ~ sentiment, value.var = "n", fill = 0) %>%
  comparison.cloud(colors = c("red", "blue"),
                   max.words = 100)

cloud_senti4<-recordPlot()
sentences1 <- tibble(text = abstracts1) %>% 
  unnest_tokens(sentence, text, token = "sentences")
sentences2 <- tibble(text = abstracts2) %>% 
  unnest_tokens(sentence, text, token = "sentences")
sentences3 <- tibble(text = abstracts3) %>% 
  unnest_tokens(sentence, text, token = "sentences")
sentences4 <- tibble(text = abstracts4) %>% 
  unnest_tokens(sentence, text, token = "sentences")

Ratios de mots positifs / négatifs pour chaque métaanalyse:

library(dplyr)
library(purrr)
library(kableExtra)

bingnegative <- get_sentiments("bing") %>% 
  filter(sentiment == "negative")

unnested_tokens1 <- unnested_tokens1 %>%
  mutate(MA = "MA1")
unnested_tokens2 <- unnested_tokens2 %>%
  mutate(MA = "MA2")
unnested_tokens3 <- unnested_tokens3 %>%
  mutate(MA = "MA3")
unnested_tokens4 <- unnested_tokens4 %>%
  mutate(MA = "MA4")

MA_labels <- c("MA1", "MA2", "MA3", "MA4")
word_counts_MA <- c(length(unnested_tokens1$word), length(unnested_tokens2$word), length(unnested_tokens3$word), length(unnested_tokens4$word))

word_count_tibble <- tibble(
  MA = MA_labels,
  words = word_counts_MA
)

all_ratios <- bind_rows(unnested_tokens1,unnested_tokens2,unnested_tokens3,unnested_tokens4)

joined_tibble <- inner_join(all_ratios, bingnegative, by = "word")

MA_titles <- c("Soil chemistry turned upside down: a meta-analysis [...]","Earthworms affect plant growth and resistance [...]","The unseen invaders: [...] in north American forests (a meta-analysis)","Earthworms increase plant production: a meta-analysis") 

summary_tibble <- joined_tibble %>%
  group_by(MA) %>%
  summarize(
    negativewords = n()
  ) %>%
  left_join(word_count_tibble, by = "MA") %>%
  mutate(ratio = negativewords / words) %>%
  ungroup() %>%
  mutate(MA_title = MA_titles) %>%
  mutate(current_MA = MA) %>%
  select(MA_title, current_MA, words, negativewords, ratio)

 summary_tibble %>%
  kbl() %>%
  kable_material_dark("hover", full_width = F) %>%
  row_spec(0, bold = T, color = "black", background = "#D7261E")
MA_title current_MA words negativewords ratio
Soil chemistry turned upside down: a meta-analysis […] MA1 5616 187 0.0332977
Earthworms affect plant growth and resistance […] MA2 2959 88 0.0297398
The unseen invaders: […] in north American forests (a meta-analysis) MA3 1860 49 0.0263441
Earthworms increase plant production: a meta-analysis MA4 4985 102 0.0204614


Ci-dessus un classement des métaanalyses contenant le plus de mots négatifs (MA1>MA2>MA3>MA4), normalisés en fonction du nombre de mots dans chaque métaanalyse (colonne “ratio”). On peut remarquer que les métaanalyses sont exactement en ordre décroissant (la MA1 est la plus négative, la MA4 la moins négative), ce qui est une coïncidence plutôt surprenante. On peut donc écrire, de manière synthétique, que:
* MA1: 3,3% des mots totaux sont des mots négatifs.
* MA2: 2,9% des mots totaux sont des mots négatifs.
* MA3: 2,6% des mots totaux sont des mots négatifs.
* MA4: 2% des mots totaux sont des mots négatifs.
Ces ratios permettent notamment d’expliquer par des proportions précises la différence observée plus tôt entre les nuages de mots bruts et les nuages de mots prenant en compte la valence (score de sentiment) des mots, les deux groupes étudiés étant de taille et de composition tès différente.

Approche tf-idf :


Définitions:
tf: term frequency.
idf: inverse document frequency. Plus élaboré que l’approche en “stop words”. Diminue la fréquence des termes rencontrés très souvent et augmente la fréquence des termes rares, en jouant sur la pondération.
tf-idf: le produit de ces deux indices. Il premet d’identifier les mots qui sont plus importants pour un document spécifique parmi un ensemble de documents.

unnested_tokens1 <- tibble(abstracts1) %>%
mutate(MA="MA1") %>%
unnest_tokens(word, abstracts1)
unnested_tokens1<-unnested_tokens1 %>% rowwise() %>% mutate(word = singularize(word))

unnested_tokens2 <- tibble(abstracts2) %>%
  mutate(MA="MA2") %>%
  unnest_tokens(word, abstracts2)
unnested_tokens2 <- unnested_tokens2 %>% rowwise() %>% mutate(word = singularize(word))

unnested_tokens3 <- tibble(abstracts3) %>%
  mutate(MA="MA3") %>%
  unnest_tokens(word, abstracts3)
unnested_tokens3 <- unnested_tokens3 %>% rowwise() %>% mutate(word = singularize(word))

unnested_tokens4 <- tibble(abstracts4) %>%
  mutate(MA="MA4") %>%
  unnest_tokens(word, abstracts4)
unnested_tokens4 <- unnested_tokens4 %>% rowwise() %>% mutate(word = singularize(word))
word_counts_MA <- c(length(unnested_tokens1$word), length(unnested_tokens2$word), length(unnested_tokens3$word),length(unnested_tokens4$word))

ordre1=unnested_tokens1 %>%
     count(word, sort = TRUE) %>%
     mutate(word = reorder(word, n,decreasing=TRUE))
tokens_ordered_1 <- left_join(unnested_tokens1, ordre1) %>%
  mutate(Total=word_count_tibble$words[1])

ordre2=unnested_tokens2 %>%
     count(word, sort = TRUE) %>%
     mutate(word = reorder(word, n,decreasing=TRUE))
tokens_ordered_2 <- left_join(unnested_tokens2, ordre2) %>%
  mutate(Total=word_count_tibble$words[2])

ordre3=unnested_tokens4 %>%
     count(word, sort = TRUE) %>%
     mutate(word = reorder(word, n,decreasing=TRUE))
tokens_ordered_3 <- inner_join(unnested_tokens3, ordre3) %>%
  mutate(Total=word_count_tibble$words[3])

ordre4=unnested_tokens4 %>%
     count(word, sort = TRUE) %>%
     mutate(word = reorder(word, n,decreasing=TRUE))
tokens_ordered_4 <- left_join(unnested_tokens4, ordre4) %>%
  mutate(Total=word_count_tibble$words[4])

all_freq <- bind_rows(tokens_ordered_1,tokens_ordered_2,tokens_ordered_3,tokens_ordered_4) %>% mutate(word_frequency = n/Total)
library(ggplot2)
library(egg)
 
word_freq_plot1 <- ggplot(all_freq, aes(x = word_frequency, fill = MA)) +
  geom_histogram(bins=100,show.legend = FALSE) +
  ggtitle("xlim = max_word_frequency") + 
  theme(plot.title = element_text(hjust = 0.5)) +
  xlim(NA, max(all_freq$word_frequency)) +
  facet_wrap(~MA, ncol = 2, scales = "free_y")

word_freq_plot2 <-ggplot(all_freq, aes(x = word_frequency, fill = MA)) +
  geom_histogram(bins=100,show.legend = FALSE) +
  ggtitle("xlim = 0.05") + 
  theme(plot.title = element_text(hjust = 0.5)) +
  xlim(NA, 0.05) +
  facet_wrap(~MA, ncol = 2, scales = "free_y")

ggarrange(word_freq_plot1,word_freq_plot2,widths = c(1,2))

Ces graphiques présentent des distributions proches pour toutes les MA, avec de nombreux mots qui apparaissent rarement et moins de mots qui apparaissent fréquemment (le premier groupe de 4 graphes représentant l’intégralité des données, le deuxième groupe de 4 se focalisant uniquement sur l’intervalle [0;0.05], pour inspecter le massif de pics davantage en détail). En x, on peut voir que les mots apparaissant très souvent (à droite) sont rares, alors que les mots qui apparaissent peu souvent (à gauche) sont fréquents. Ces graphiques présentent des distributions similaires pour toutes les MA, avec de nombreux mots qui apparaissent rarement et moins de mots qui apparaissent fréquemment.

Loi de Zipf:


La loi de Zipf, découverte empiriquement par Zipf (1949) pour des mots d’un corpus anglais, stipule que si f est la fréquence d’un mot dans le corpus et r le rang, alors :
\(frequency \propto \frac{1}{rank}\)
(la fréquence d’un mot donné est inversement proportionnelle à son rang).

library(latex2exp)

freq_and_rank <-  all_freq %>% group_by(MA) %>%
    distinct(word, .keep_all = TRUE) %>%
    arrange(desc(n)) %>%
    mutate(rank = seq_len(length(word)), word_frequency = n/Total) %>% # 
    ungroup()

freq_and_rank %>% 
    ggplot(aes(rank, word_frequency, color = MA)) + 
    geom_line(linewidth = 1.1, alpha = 0.8, show.legend = TRUE) + 
    scale_x_log10() +
    scale_y_log10() +
  xlab(TeX("$\\log_{10}(Rank)$")) +
  ylab(TeX("$\\log_{10}(Word~Frequency)$"))


Les courbes de Zipf (log10(f) contre log10(r)) obtenues ci-dessus ont une pente négative. On peut visualiser graphiquement qu’il existe bel et bien une relation inversement proportionnelle entre f et r (échelle logarithmique). On peut cependant remarquer que la décroissance observée n’est pas strictement monotone. On pourrait considérer ces courbes comme des lois de puissance brisées (fonction par morceaux donnée par une séquence de lois de puissance jointes où chaque section a sa propre puissance (indice) et est définie par des “ruptures” limitatives.) et les diviser en trois sections: [1;10]/[10;100]/[100;1000]. Voyons quel est l’exposant de la loi de puissance pour la partie centrale de la plage de rangs.

rank_subset <- freq_and_rank %>% 
  filter(rank < 100,
         rank > 10)
lm(log10(word_frequency) ~ log10(rank), data = rank_subset)
## 
## Call:
## lm(formula = log10(word_frequency) ~ log10(rank), data = rank_subset)
## 
## Coefficients:
## (Intercept)  log10(rank)  
##     -0.8048      -0.8272
library(latex2exp)

freq_and_rank %>% ggplot(aes(rank, word_frequency, color = MA)) + 
  geom_abline(intercept = -0.8048, slope = -0.8272, 
              color = "gray50", linetype = 2) +
  geom_line(linewidth = 1.1, alpha = 0.8, show.legend = TRUE) + 
  scale_x_log10() +
  scale_y_log10() +
  xlab(TeX("$\\log_{10}(Rank)$")) +
  ylab(TeX("$\\log_{10}(Word~Frequency)$"))

On peut remarquer en ragardant la partie supérieure que la MA3 contient davantage de mots “rares” que la valeur prédite par le modèle linéaire, alors que toutes les autres (courbes orange, vertes et blues) en contiennent moins. La MA3 est donc celle qui contient la plus haute fréquence de mots rares. Ce résultat semble logique lorsqu’on considère que c’est aussi elle qui comprends le moins de mots totaux (MA3=1860 < MA2=2959 < MA4=4985 < MA1=5616, voir table ci-dessous). Pour ce qui est des mots très fréquents (quart inférieur droit sous 0.001 de fréquence), on peut constater que toutes les métaanalyses en contiennent moins que la valeur prédite. Au centre, les courbes des 4 MA sont relativement proche du modèle linéaire, ce qui n’est pas particulièrement étonnant car il a justement été ajusté pour convenir à l’intervalle correspondant à la partie centrale du graphe.

word_count_tibble%>%
  kbl() %>%
  kable_material_dark("hover", full_width = F) %>%
  row_spec(0, bold = T, color = "black", background = "#D7261E")
MA words
MA1 5616
MA2 2959
MA3 1860
MA4 4985

Fonction bind_tf_idf:


MA_tf_idf <- all_freq %>%
  distinct(word, .keep_all = TRUE) %>%
  select(-word_frequency) %>%
  select(-Total) %>%
  bind_tf_idf(word, MA, n) %>%
  arrange(desc(tf_idf))

MA_tf_idf 
## # A tibble: 2,762 × 6
## # Rowwise: 
##    MA    word             n     tf   idf tf_idf
##    <chr> <chr>        <int>  <dbl> <dbl>  <dbl>
##  1 MA3   become           4 0.0833  1.39 0.116 
##  2 MA3   tim              4 0.0833  1.39 0.116 
##  3 MA3   k                4 0.0833  1.39 0.116 
##  4 MA3   contribute       3 0.0625  1.39 0.0866
##  5 MA1   the            488 0.0494  1.39 0.0685
##  6 MA1   and            456 0.0462  1.39 0.0640
##  7 MA2   aphid           50 0.0456  1.39 0.0632
##  8 MA1   of             425 0.0430  1.39 0.0597
##  9 MA3   accumulation     2 0.0417  1.39 0.0578
## 10 MA3   april            2 0.0417  1.39 0.0578
## # ℹ 2,752 more rows
library(forcats)

MA_tf_idf %>%
  anti_join(stop_words) %>%
  anti_join(custom_stop_words) %>%
  group_by(MA) %>%
  slice_max(tf_idf, n = 15) %>%
  ungroup() %>%
  ggplot(aes(tf_idf, fct_reorder(word, tf_idf), fill = MA)) +
  geom_col(show.legend = FALSE) +
  facet_wrap(~MA, ncol = 2, scales = "free") +
  labs(x = "tf-idf", y = NULL)

D’après les graphiques ci-dessus, on peut constater que:
- Les mots “earthworm”, “soil”, “forest” et “effect” sont plus souvent employés dans la MA1 que dans les autres MA. Le mot “invasion” est aussi plus présent dans la MA1 que dans les autres MA.
- Les mots “aphid, ”nematode”, “organism” et “herbivore” sont plus souvent employés dans la MA2 que dans les autres MA. Le mot “parasitoid” est aussi plus présent dans la MA2 que dans les autres MA.
- Les mots “tim” (forme de “times” après ‘singularize’?), “contribute”, “stage” et “responsible” sont plus souvent employés dans la MA3 que dans les autres MA.
Les mots “canopy” et “aggregate” sont aussi plus présent dans la MA3 que dans les autres MA.
- Les mots “maize, ”gtt”, “grain” et “herbivore” sont plus souvent employés dans la MA4 que dans les autres MA. Les mots du champs lexical de l’agriculture, comme “harvest”, “fertilizer”, “farmer” et “pb” (probablement employé ici comme le symbole chimique du plomb) sont aussi plus présent dans la MA4 que dans les autres MA.

Rappelons les suppositions faites précédemment dans la partie “Analyse de sentiment”:
- MA1/MA3: étude de l’impact écologique des vers de terre sur les écosystèmes.
- MA2: étude des effets des vers de terre sur la physiologie végétale.
- MA4: étude de l’influence des vers de terre invasifs sur la production végétale.

En prenant en compte le sujet apparent de chaque métaanalyse, on peut supposer que:
- La MA1 se focalise plus que les autres sur l’impact écologique des vers de terre sur les forêts, sous la modalité d’une “invasion” biologique.
- La MA2 se focalise plus que les autres sur les organismes herbivores comme les pucerons (“aphids”). Le mot “parasitoid” laisse entendre un effet parasitaire des pucerons sur les végétaux. Cela semble cohérent avec les résultats obtenus précédemment (voir “Analyse de sentiment” et “Wordcloud: coloration en fonction de la valence des mots”). D’après le titre de la métaanalyse, les vers de terre semblent par contre avoir une influence positive sur la résistance des plantes aux pucerons (id.).
- La MA3 se focalise plus que les autres sur les effets des vers de terre sur les forêts (d’après le titre et le mot-clé “canopy”), et sur les aggrégats, peut-être chimiques ou biochimiques, présents dans le sol.
- La MA4 se focalise plus que les autres sur les effets des vers de terre sur la production végétale (comme semble l’indiquer le mot PLFA (acides gras phospholipidiques), un marqueur de la biomasse vivante), d’après le titre de la métaanalyse et le champs lexical abondant en lien avec le monde agricole (“maize”, “grain”, “herbivore”,“harvest”, “fertilizer”, “farmer” et “pb”). Le terme “Pb” semble indiquer que la métanalyse s’intéresse probablement aux conséquences écosystémiques des métaux lourds présents dans le sol.


MA1: “Soil chemistry turned upside down: a meta-analysis of invasive earthworm effects on soil chemical properties”
MA2: “Earthworms affect plant growth and resistance against herbivores: A meta-analysis”
MA3: “The unseen invaders: introduced earthworms as drivers of change in plant communities in North American forests (a meta-analysis)”
MA4: “Earthworms increase plant production: a meta-analysis”

n-grams et corrélations :


library(dplyr)
library(tidytext)

all_abstracts_df <- rbind(data.frame(abstract = abstracts1, MA = "MA1"),
      data.frame(abstract = abstracts2, MA = "MA2"),
      data.frame(abstract = abstracts3, MA = "MA3"), 
      data.frame(abstract = abstracts4, MA = "MA4"))

tokens_bigrams_all <- tibble(all_abstracts_df) %>%
  unnest_tokens(bigram, abstract, token = "ngrams", n = 2) %>%
  filter(!is.na(bigram))

tokens_bigrams1 <- tibble(abstracts1) %>%
  unnest_tokens(bigram, abstracts1, token = "ngrams", n = 2) %>%
  filter(!is.na(bigram))

tokens_bigrams2 <- tibble(abstracts2) %>%
  unnest_tokens(bigram, abstracts2, token = "ngrams", n = 2) %>%
  filter(!is.na(bigram))

tokens_bigrams3 <- tibble(abstracts3) %>%
  unnest_tokens(bigram, abstracts3, token = "ngrams", n = 2) %>%
  filter(!is.na(bigram))

tokens_bigrams4 <- tibble(abstracts4) %>%
  unnest_tokens(bigram, abstracts4, token = "ngrams", n = 2) %>%
  filter(!is.na(bigram))

tokens_bigrams1 %>% count(bigram, sort = TRUE)
## # A tibble: 6,279 × 2
##    bigram                 n
##    <chr>              <int>
##  1 in the                81
##  2 of the                73
##  3 effects of            31
##  4 microbial biomass     31
##  5 organic matter        29
##  6 of earthworm          26
##  7 of earthworms         26
##  8 earthworm invasion    25
##  9 forest floor          25
## 10 c and                 24
## # ℹ 6,269 more rows
tokens_bigrams2 %>%
 count(bigram, sort = TRUE)
## # A tibble: 3,564 × 2
##    bigram            n
##    <chr>         <int>
##  1 in the           35
##  2 of earthworms    34
##  3 effects of       31
##  4 presence of      31
##  5 the presence     30
##  6 of the           28
##  7 on the           18
##  8 plant species    17
##  9 plant growth     16
## 10 affected by      15
## # ℹ 3,554 more rows
tokens_bigrams3 %>%
 count(bigram, sort = TRUE)
## # A tibble: 2,448 × 2
##    bigram                n
##    <chr>             <int>
##  1 of the               19
##  2 in the               16
##  3 non native           15
##  4 plant species        15
##  5 native plant         14
##  6 earthworm species    11
##  7 of earthworm         11
##  8 and the              10
##  9 o tyrtaeum           10
## 10 changes in            9
## # ℹ 2,438 more rows
tokens_bigrams4 %>%
 count(bigram, sort = TRUE)
## # A tibble: 6,044 × 2
##    bigram              n
##    <chr>           <int>
##  1 in the             80
##  2 of the             64
##  3 presence of        43
##  4 the presence       41
##  5 of earthworms      34
##  6 on the             28
##  7 the soil           27
##  8 plant community    26
##  9 effects of         25
## 10 in a               23
## # ℹ 6,034 more rows

De nombreux bigrammes sont non-informatifs (“in the”, “of the” etc.). On va donc réemployer l’approche en “stop words” des étapes précédentes pour enlever ces mots.

# bigrams ok, separated ok,  filtered ok.
bigrams_separated_all <- tokens_bigrams_all %>%
  separate(bigram, c("word1", "word2"), sep = " ")

bigrams_separated1 <- tokens_bigrams1 %>%
  separate(bigram, c("word1", "word2"), sep = " ")

bigrams_filtered_all <- bigrams_separated_all %>% 
  filter(!word1 %in% combined_stop_words$word) %>%
  filter(!word2 %in% combined_stop_words$word)

bigrams_filtered1 <- bigrams_separated1 %>%
  filter(!word1 %in% combined_stop_words$word) %>%
  filter(!word2 %in% combined_stop_words$word)

# new bigram counts:
bigram_counts_all <- bigrams_filtered_all %>%
  count(MA, word1, word2, sort = TRUE)

bigram_counts1 <- bigrams_filtered1 %>% 
  count(word1, word2, sort = TRUE)

# For bigrams_2
bigrams_separated2 <- tokens_bigrams2 %>%
  separate(bigram, c("word1", "word2"), sep = " ")

bigrams_filtered2 <- bigrams_separated2 %>%
  filter(!word1 %in% combined_stop_words$word) %>%
  filter(!word2 %in% combined_stop_words$word)

bigram_counts2 <- bigrams_filtered2 %>% 
  count(word1, word2, sort = TRUE)

# For bigrams_3
bigrams_separated3 <- tokens_bigrams3 %>%
  separate(bigram, c("word1", "word2"), sep = " ")

bigrams_filtered3 <- bigrams_separated3 %>%
  filter(!word1 %in% combined_stop_words$word) %>%
  filter(!word2 %in% combined_stop_words$word)

bigram_counts3 <- bigrams_filtered3 %>% 
  count(word1, word2, sort = TRUE)

# For bigrams_4
bigrams_separated4 <- tokens_bigrams4 %>%
  separate(bigram, c("word1", "word2"), sep = " ")

bigrams_filtered4 <- bigrams_separated4 %>%
  filter(!word1 %in% combined_stop_words$word) %>%
  filter(!word2 %in% combined_stop_words$word)

bigram_counts4 <- bigrams_filtered4 %>% 
  count(word1, word2, sort = TRUE)

bigrams_united_all <- bigrams_filtered_all %>%
  unite(bigram, word1, word2, sep = " ")

bigrams_united_all %>% count(MA, bigram, sort = TRUE)
## # A tibble: 5,515 × 3
##    MA    bigram                 n
##    <chr> <chr>              <int>
##  1 MA1   microbial biomass     31
##  2 MA1   organic matter        29
##  3 MA4   plant community       26
##  4 MA1   earthworm invasion    25
##  5 MA1   forest floor          25
##  6 MA1   exotic earthworms     24
##  7 MA1   mineral soil          23
##  8 MA1   earthworm species     18
##  9 MA2   plant species         17
## 10 MA4   plant growth          17
## # ℹ 5,505 more rows
earthworms_bigrams <- bigrams_united_all %>%
    filter(grepl("earthworms?", bigram, ignore.case = TRUE))
# Count occurrences of MA and word2 combination, sorted in descending order
count_earthworm_bigrams<- earthworms_bigrams %>%
    count(MA, bigram, sort = TRUE) %>%
    group_by(MA) %>%
    filter(n>5) %>%
    mutate(MA = factor(MA, levels = c("MA1", "MA2", "MA3", "MA4"))) %>% # Set the order of MA
    arrange(MA, desc(n)) # Sort by MA and then by n in descending order
count_earthworm_bigrams
## # A tibble: 22 × 3
## # Groups:   MA [4]
##    MA    bigram                   n
##    <fct> <chr>                <int>
##  1 MA1   earthworm invasion      25
##  2 MA1   exotic earthworms       24
##  3 MA1   earthworm species       18
##  4 MA1   earthworm activity       9
##  5 MA1   earthworm biomass        8
##  6 MA1   earthworm invaded        7
##  7 MA1   european earthworms      7
##  8 MA1   exotic earthworm         7
##  9 MA1   earthworm community      6
## 10 MA2   earthworms increased     7
## # ℹ 12 more rows
library(dplyr)

# Define the function
count_filtered_bigrams <- function(data, regex_motif,treshold) {
  # Filter the bigrams based on the provided regex motif
  filtered_bigrams <- data %>%
    filter(grepl(regex_motif, bigram, ignore.case = TRUE))
  
  # Count occurrences of each combination of `MA` and `bigram`, sort in descending order,
  # group by `MA`, and filter counts greater than 5 within each group
  count_bigrams <- filtered_bigrams %>%
    count(MA, bigram, sort = TRUE) %>%
    group_by(MA) %>%
    filter(n > treshold) %>%
    mutate(MA = factor(MA, levels = c("MA1", "MA2", "MA3", "MA4"))) %>%
    arrange(MA, desc(n)) # Sort by MA and then by n in descending order
  
  return(count_bigrams)
}

count_filtered_bigrams(bigrams_united_all,"earthworms?",5)
## # A tibble: 22 × 3
## # Groups:   MA [4]
##    MA    bigram                   n
##    <fct> <chr>                <int>
##  1 MA1   earthworm invasion      25
##  2 MA1   exotic earthworms       24
##  3 MA1   earthworm species       18
##  4 MA1   earthworm activity       9
##  5 MA1   earthworm biomass        8
##  6 MA1   earthworm invaded        7
##  7 MA1   european earthworms      7
##  8 MA1   exotic earthworm         7
##  9 MA1   earthworm community      6
## 10 MA2   earthworms increased     7
## # ℹ 12 more rows
count_filtered_bigrams(bigrams_united_all,"invasions?",5)
## # A tibble: 3 × 3
## # Groups:   MA [2]
##   MA    bigram                  n
##   <fct> <chr>               <int>
## 1 MA1   earthworm invasion     25
## 2 MA3   earthworm invasion      7
## 3 MA3   earthworm invasions     6
count_filtered_bigrams(bigrams_united_all,"invaders?",0)
## # A tibble: 9 × 3
## # Groups:   MA [2]
##   MA    bigram                 n
##   <fct> <chr>              <int>
## 1 MA1   earthworm invaders     1
## 2 MA1   invaders affect        1
## 3 MA4   invader plants         2
## 4 MA4   invader species        2
## 5 MA4   plant invader          2
## 6 MA4   invader biomass        1
## 7 MA4   invader seed           1
## 8 MA4   invader treatments     1
## 9 MA4   plant invaders         1
count_filtered_bigrams(bigrams_united_all,"europeans?",0)
## # A tibble: 23 × 3
## # Groups:   MA [4]
##    MA    bigram                  n
##    <fct> <chr>               <int>
##  1 MA1   european earthworms     7
##  2 MA1   european species        5
##  3 MA1   european earthworm      4
##  4 MA1   european settlers       2
##  5 MA1   introduced european     2
##  6 MA1   invasive european       2
##  7 MA1   european lumbricids     1
##  8 MA1   exotic european         1
##  9 MA1   processes european      1
## 10 MA1   time european           1
## # ℹ 13 more rows
bigram_tf_idf <- bigrams_united_all %>%
  count(MA, bigram) %>%
  bind_tf_idf(bigram, MA, n) %>%
  arrange(desc(tf_idf))

bigram_tf_idf %>%
    group_by(MA) %>%
    slice_max(tf_idf, n = 15) %>%
    ungroup() %>%
    ggplot(aes(tf_idf, fct_reorder(bigram, tf_idf), fill = MA)) +
    geom_col(show.legend = FALSE) +
    facet_wrap(~MA, ncol = 2, scales = "free") +
    labs(x = "tf-idf", y = NULL)


D’après les graphiques ci-dessus, on peut constater que:
Les bigrammes “mineral soil”, “earthworm invasion”, “exotic earthworms” et “forest soils” sont plus souvent employés dans la MA1 que dans les autres MA. Le bigramme “earthworm invaded” est aussi plus présent dans la MA1 que dans les autres MA.
Les bigrammes “soil organisms”, “plant responses”, “plant mediated” et “root herbivore” sont plus souvent employés dans la MA2 que dans les autres MA. Le bigramme “aphid species” est aussi plus présent dans la MA2 que dans les autres MA.
Les bigrammes “tree species”, “native plant”, “species richness” et “caterpillar density” sont plus souvent employés dans la MA3 que dans les autres MA. Le bigramme “earthworm invasions” est aussi plus présent dans la MA3 que dans les autres MA.
Les bigrammes “soil organisms”, “plant functionnal”, “dry weight” et “diplocardia spp” sont plus souvent employés dans la MA4 que dans les autres MA. Le bigramme “soil fertility” est aussi plus présent dans la MA4 que dans les autres MA.

Rappelons les suppositions faites dans la section précédente:
- La MA1 se focalise plus que les autres sur l’impact écologique des vers de terre sur les forêts, sous la modalité d’une “invasion” biologique.
- La MA2 se focalise plus que les autres sur les organismes herbivores comme les pucerons (“aphids”). Le mot “parasitoid” laisse entendre un effet parasitaire des pucerons sur les végétaux. Cela semble cohérent avec les résultats obtenus précédemment (voir “Analyse de sentiment” et “Wordcloud: coloration en fonction de la valence des mots”). D’après le titre de la métaanalyse, les vers de terre semblent par contre avoir une influence positive sur la résistance des plantes aux pucerons (id.).
- La MA3 se focalise plus que les autres sur les effets des vers de terre sur les forêts (d’après le titre et le mot-clé “canopy”), et sur les aggrégats, peut-être chimiques ou biochimiques, présents dans le sol.
- La MA4 se focalise plus que les autres sur les effets des vers de terre sur la production végétale (comme semble l’indiquer le mot PLFA (acides gras phospholipidiques), un marqueur de la biomasse vivante), d’après le titre de la métaanalyse et le champs lexical abondant en lien avec le monde agricole (“maize”, “grain”, “herbivore”,“harvest”, “fertilizer”, “farmer” et “pb”). Le terme “Pb” semble indiquer que la métanalyse s’intéresse probablement aux conséquences écosystémiques des métaux lourds présents dans le sol.

En prenant en compte le sujet apparent de chaque métaanalyse, on peut supposer que:
- La MA1 se focalise plus que les autres sur l’impact écologique des vers de terre “exotiques” sur l’écosystème du sol forestier, sous la modalité d’une “invasion” biologique.
- La MA2 se focalise plus que les autres sur l’effet des “organismes du sol”, et plus précisément ceux affectant les “racines”, sur les plantes, en observant notamment, probablement, les stratégies d’adaptation des plante face à cette source de stress biotique (“plant responses”). Les “espèces de pucerons” semblent particulièrement ciblées comme étant la source de ce stress.
- La MA3 se focalise plus que les autres sur l’impact écologique (“species richness”, “caterpillar density”,“tree species”,“native plants”) des vers de terre invasifs (“earthworm invasions”) sur les forêts d’Amérique du nord. Le champ lexical de la richesse spécifique et de la diversité, ainsi que le wordlcoud de la partie “Wordcloud: coloration en fonction de la valence des mots (bleu: Positif / rouge: Négatif)”, semble évoquer un “déclin”, un “dommage”, une “destruction”. On peut donc en conclure que dans cette MA, les vers de terre invasifs sont dépeints comme des nuisibles majeurs contre l’écosystème natif nord américain.
- La MA4 se focalise plus que les autres sur les effets des vers de terre et des organismes du sol sur la production (“dry weight”) et la physiologie végétale (“plant functionnal”). Elle s’intéresse aussi à la fertilité des sol, ce qui semble cohérent avec le champ lexical agricole relevé plus tôt (“maize”, “grain”, “herbivore”,“harvest”, “fertilizer”, “farmer” et “pb”). Le terme “Pb” semble indiquer que la métanalyse s’intéresse probablement aux conséquences écosystémiques des métaux lourds présents dans le sol.


MA1: “Soil chemistry turned upside down: a meta-analysis of invasive earthworm effects on soil chemical properties”
MA2: “Earthworms affect plant growth and resistance against herbivores: A meta-analysis”
MA3: “The unseen invaders: introduced earthworms as drivers of change in plant communities in North American forests (a meta-analysis)”
MA4: “Earthworms increase plant production: a meta-analysis”

n-grams et analyse de sentiment:


 library(ggplot2)

AFINN <-get_sentiments("afinn")

not_words <- bigrams_separated_all %>%
  filter(word1 == "not") %>%
  inner_join(AFINN, by = c(word2 = "word")) %>%
  count(word2, value, sort = TRUE)

not_words %>%
  mutate(contribution = n * value) %>%
  arrange(desc(abs(contribution))) %>%
  mutate(word2 = reorder(word2, contribution)) %>%
  ggplot(aes(contribution, word2, fill = contribution > 0)) +
  geom_col(show.legend = FALSE) +
  labs(x = "Sentiment value * number of occurrences",
       y = "Words preceded by \"not\"")

## Les bigrammes “not benefit” et “not increase” sont les plus important facteur d’erreur d’identification, faisant paraître le texte plus positif qu’il ne l’est réellement.
Le bigramme “not affected” est le plus important facteur d’erreur d’identification, faisant paraître le texte plus négatif qu’il ne l’est réellement.

library(ggplot2)

AFINN <-get_sentiments("afinn")
bigrams_separated1 %>%
  filter(word1 == "not") %>%
  inner_join(AFINN, by = c(word2 = "word")) %>%
  count(word2, value, sort = TRUE)
## # A tibble: 2 × 3
##   word2    value     n
##   <chr>    <dbl> <int>
## 1 benefit      2     1
## 2 increase     1     1
not_words_with_factor <- bigrams_separated_all %>%
    filter(word1 == "not") %>%
    inner_join(AFINN, by = c(word2 = "word")) %>%
    count(MA, word2, value, sort = TRUE)

not_words_with_factor %>%
  mutate(contribution = n * value) %>%
  arrange(desc(abs(contribution))) %>%
  mutate(word2 = reorder(word2, contribution)) %>%
  ggplot(aes(contribution, word2, fill = contribution > 0)) +
  geom_col(show.legend = FALSE) +
  labs(x = "Sentiment value * number of occurrences",
       y = "Words preceded by \"not\"") + 
  coord_fixed(ratio = 0.25)+
  facet_wrap(facets = vars(MA), ncol = 1)


Lorsque l’on inspecte le jeu de données pour chacune des MA avec la fonction R “facet_grid”, on remarque que les mots ayant conduit au plus d’erreurs d’identification dans chaque MA sont:
- MA1: “benefit” et “increase” classés à tort en positif (comme le mot précédant était “not”, “not benefit” et “not increase” ont une valance négative), pas de négatif relevé.
- MA2: Pas de mot positif relevé. “affected” classé à tort en négatif (comme le mot précédent était “not”, “not affected” a une valence positive).
- MA3: Pas de mot positif relevé. “affected” classé à tort en négatif (comme le mot précédent était “not”, “not affected” a une valence positive). On remarque cependant que l’effet observé est moindre comparé à la MA2.
- MA4: “responsible” (donc, le bigramme “not responsible”), est classé positif par le dictionnaire AFINN, mais ces seuls deux mots ne suffisent pas à déterminer la valence (positive ou négative), de l’expression. Elles traduisent au contraire une forme de neutralité (quelque-chose qui est non responsable d’un effet est à priori neutre). Une analyse plus détaillée du contexte d’utilisation serait requise pour pouvoir décider. Dans AFINN (dictionnaire), “prevent” est classé négatif (c’est pourquoi “not prevent” a une valence positive), mais en écologie, “not prevent” semble bel et bien négatif (il n’y a donc pas d’erreur d’identification dans cas précis). Par contre, classé à tort en négatif, on retrouve là-aussi “affected”, dans ce cas précédé par “not”, et donc de valence plutôt positive.
Cependant, d’autres mots négatifs (comme “never” etc.) n’ont pas été pris en compte dans l’analyse ci-dessus. La prochaine étape à donc pour but de prendre davantage de mots de négation en considération dans l’analyse de sentiment.

negation_words <- c("ain't", "aren't", "can't", "couldn't", "didn't", "doesn't", "don't", "hasn't", 
                    "isn't", "mightn't", "mustn't", "neither", "never", "no", "nobody", "nor", 
                    "not", "shan't", "shouldn't", "wasn't", "weren't", "won't", "wouldn't","without")
bigrams_separated_all %>%
    filter(word1 %in% negation_words) %>%
    inner_join(AFINN, by = c(word2 = "word"))
## # A tibble: 28 × 4
##    MA    word1   word2       value
##    <chr> <chr>   <chr>       <dbl>
##  1 MA1   no      significant     1
##  2 MA1   no      significant     1
##  3 MA1   not     increase        1
##  4 MA1   no      greater         3
##  5 MA1   not     benefit         2
##  6 MA1   no      significant     1
##  7 MA1   no      significant     1
##  8 MA1   neither affected       -1
##  9 MA1   no      significant     1
## 10 MA2   not     affected       -1
## # ℹ 18 more rows
library(dplyr)
library(ggplot2)
library(tidyr)

negation_words_with_factor <- bigrams_separated_all %>%
    filter(word1 %in% negation_words) %>%
    inner_join(AFINN, by = c(word2 = "word")) %>%
    count(MA, word1, word2, value, sort = TRUE)
negation_words_with_factor %>%
   mutate(contribution = n * value) %>%
   arrange(desc(abs(contribution))) %>%
   mutate(word2 = reorder(word2, contribution)) %>%
   ggplot(aes(contribution, word2, fill = contribution > 0)) +
   geom_col(show.legend = FALSE) +
   labs(x = "Sentiment value * number of occurrences",
        y = "Words preceded by negation word") + 
   coord_fixed(ratio = 0.25)+
   facet_wrap(facets = vars(word1), ncol = 2)


Le fig.height agrandit l’espace blanc nul mais pas la figure. What the fuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuck, comme dirait le Big E.